/**
 * Copyright (C) 2011 Andrew C. Love (DNC) <dnc.app.sup@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.dnc.cloak.service;

import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.apache.log4j.Logger;

import com.dnc.cloak.framework.context.Context;
import com.dnc.cloak.framework.messaging.EmailMessage;
import com.dnc.cloak.framework.service.ServiceException;
import com.dnc.cloak.service.gen.LogServiceImpl;

/*
log.mail.smtp.protocol=smtps
log.mail.smtp.port=-1
log.mail.smtp.debug=false
log.mail.to=drewncrew@gmail.com
log.mail.from=spiro@michiganbread.com
log.mail.smtp.server=smtp.gmail.com
log.mail.smtpusername=drewncrew@gmail.com
log.mail.smtppassword=11521151
log.mail.smtp.buffersize=1024
log.mail.subject=Route Order Management Application Error
*/

public class MessageServiceImpl extends LogServiceImpl implements MessageService {
    private static final Logger logger = Logger.getLogger(MessageService.class.getName());
    
    private SecurityService securityService;
    

    public SecurityService getSecurityService() {
        return securityService;
    }


    public void setSecurityService(SecurityService securityService) {
        this.securityService = securityService;
    }

    @Override
    public void email(Context context, EmailMessage emailMessage) throws ServiceException {
        ServiceException serviceException = null;
        try {
            postMail(emailMessage);
        }
        catch (MessagingException ex) {
            serviceException =  new ServiceException(ex);
            throw serviceException;
        }
        
    }

    @Override
    public void email(Context context, List<EmailMessage> emailMessages) throws ServiceException {
        ServiceException serviceException = null;
        for (EmailMessage emailMessage : emailMessages) {
            try {
                postMail(emailMessage);
            }
            catch (MessagingException ex) {
                if (serviceException == null) {
                    serviceException = new ServiceException(ex);
                }
                else {
                    serviceException = new ServiceException(serviceException);
                }
            }
        }
        if (serviceException != null) {
            throw serviceException;
        }
    }
        
        
    private void postMail(EmailMessage emailMessage) throws MessagingException {
        if (logger.isDebugEnabled()){
            logger.debug(emailMessage.toString());
        }

        javax.mail.Session session = createSession(emailMessage);

        // create a message
        javax.mail.Message msg = new MimeMessage(session);

        // set the from and to address
        InternetAddress addressFrom = new InternetAddress(emailMessage.getMailFrom());
        msg.setFrom(addressFrom);

        // To
        InternetAddress[] addressTo = new InternetAddress[emailMessage.getMailToList().size()];
        for (int i = 0; i < emailMessage.getMailToList().size(); i++) {
            addressTo[i] = new InternetAddress(emailMessage.getMailToList().get(i));
        }
        msg.setRecipients(Message.RecipientType.TO, addressTo);

        // CC
        if (emailMessage.getMailToCcList() != null) {
            InternetAddress[] addressCc = new InternetAddress[emailMessage.getMailToCcList().size()];
            for (int i = 0; i < emailMessage.getMailToCcList().size(); i++) {
                addressCc[i] = new InternetAddress(emailMessage.getMailToCcList().get(i));
            }
            msg.setRecipients(Message.RecipientType.CC, addressCc);
        }

        // BCC
        if (emailMessage.getMailToBccList() != null) {
            InternetAddress[] addressBcc = new InternetAddress[emailMessage.getMailToBccList().size()];
            for (int i = 0; i < emailMessage.getMailToBccList().size(); i++) {
                addressBcc[i] = new InternetAddress(emailMessage.getMailToBccList().get(i));
            }
            msg.setRecipients(Message.RecipientType.BCC, addressBcc);
        }

        // Reply To
        if (emailMessage.getMailReplyToList() != null) {
            InternetAddress[] addressReplyTo = new InternetAddress[emailMessage.getMailReplyToList().size()];
            for (int i = 0; i < emailMessage.getMailReplyToList().size(); i++) {
                addressReplyTo[i] = new InternetAddress(emailMessage.getMailReplyToList().get(i));
            }
            msg.setReplyTo(addressReplyTo);
        }

        // Setting the Subject and Content Type
        msg.setSubject(emailMessage.getSubject());
        msg.setContent(emailMessage.getMessage(), emailMessage.getContentType());
        msg.setSentDate(new Date());

        Transport.send(msg);
        
    }        
        
    private javax.mail.Session createSession(EmailMessage emailMessage) {
        Properties props = null;

        try {
            props = new Properties(System.getProperties());
        }
        catch (SecurityException ex) {
            props = new Properties();
        }

        String prefix = "mail.smtp";
        if (emailMessage.getSmtpProtocol() != null) {
            props.put("mail.transport.protocol", emailMessage.getSmtpProtocol());
            prefix = "mail." + emailMessage.getSmtpProtocol();
        }
        if (emailMessage.getSmtpHost() != null) {
            props.put(prefix + ".host", emailMessage.getSmtpHost());
        }
        if (emailMessage.getPort() > 0) {
            props.put(prefix + ".port", String.valueOf(emailMessage.getPort()));
        }

        Authenticator auth = null;

        if (emailMessage.getSmtpPassword() != null && emailMessage.getSmtpUser() != null) {
            final String smtpUsername = emailMessage.getSmtpUser();
            final String smtpPassword = emailMessage.getSmtpPassword();

            props.put(prefix + ".starttls.enable", "true");
            props.put(prefix + ".auth", "true");

            auth = new Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(smtpUsername, smtpPassword);
                }
            };
        }
        javax.mail.Session session = javax.mail.Session.getInstance(props, auth);
        
        if (emailMessage.getSmtpProtocol() != null) {
            session.setProtocolForAddress("rfc822", emailMessage.getSmtpProtocol());
        }
        if (emailMessage.getSmtpDebug()) {
            session.setDebug(emailMessage.getSmtpDebug());
        }

        return session;
    }     
   

}
